home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 376-400 / disk_376 / toollibrary / src / parser.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  21KB  |  962 lines

  1.  
  2.  /********************************************************************/
  3.  /****                                                            ****/
  4.  /****                                                            ****/
  5.  /****    Program          : Parser.c Baum                        ****/
  6.  /****                                                            ****/
  7.  /****    Version          :    01.15                             ****/
  8.  /****                                                            ****/
  9.  /****    Erstversion      : 21.05.1988                           ****/
  10.  /****                                                            ****/
  11.  /****    Letzte Änderung  : 05.08.1990                           ****/
  12.  /****                                                            ****/
  13.  /****    Compiliert mit   : siehe MAKEFILE                       ****/
  14.  /****                                                            ****/
  15.  /****    Gelinkt mit      : Für Tool.Library                     ****/
  16.  /****                                                            ****/
  17.  /********************************************************************/
  18.  /****                                                            ****/
  19.  /****                                                            ****/
  20.  /****               Copyright by Rüdiger Dreier                  ****/
  21.  /****                                                            ****/
  22.  /****                                                            ****/
  23.  /********************************************************************/
  24.  
  25.  /* 04.12.1989: Alle Konstanten außer e und x möglich   */
  26.  /* 19.12.1989: Fehler in PreCalc bei pi/e beseitigt    */
  27.  
  28.  #include "ToolProto.h"
  29.  #include <string.h>
  30.  #include <exec/memory.h>
  31.  
  32.  extern struct Library *MathIeeeDoubBasBase;
  33.  extern struct Library *MathIeeeDoubTransBase;
  34.  int search(char *string);
  35.  
  36.  int search(char *string)
  37.   {
  38.    int i,a,Fehler=0;
  39.    char VERGLEICH[38];
  40.    if(strlen(string)==NULL)return(-1);
  41.    strcpy(VERGLEICH,"xeintasinatanacossqrlogabssgnlnpi");
  42.    for(i=0;i<=strlen(VERGLEICH)-1;i++)
  43.     {
  44.      Fehler=0;
  45.      for(a=0;a<=strlen(string)-1;a++)
  46.       {
  47.        if(string[a]!=VERGLEICH[i+a])Fehler=-1;
  48.       }
  49.      if(Fehler==0)break;
  50.     }
  51.    if(Fehler==-1)i=-1;
  52.    if(strlen(string)==1&&i>1)i=-1;
  53.    return(i);
  54.   }
  55.  
  56.  /* Diese Funktion arbeitet einen String ab und legt entsprechend einen */
  57.  /* Baum im Speicher an.                                                */
  58.  LONG __asm ev(register __d0 LONG l,register __d1 LONG r,register __d2 struct Block *block)
  59.   {
  60.    char Hilfe[9];
  61.    char Ziffern[100];
  62.    struct Block *BL,*BR;
  63.    LONG Fehler=0;
  64.    int Pos1,Anzahl_Zeichen;
  65.    char Exponent_gefunden;
  66.    
  67.    block->Links=l;
  68.    block->Rechts=r;
  69.    
  70.    if(r<l)return(0);
  71.    
  72.    BL=(struct Block *)AllocMem(sizeof(struct Block),MEMF_CLEAR);
  73.    if(BL==NULL)return(NO_MEM);
  74.    BR=(struct Block *)AllocMem(sizeof(struct Block),MEMF_CLEAR);
  75.    if(BR==NULL)
  76.     {
  77.      FreeMem((UBYTE *)BL,sizeof(struct Block));
  78.      return(NO_MEM);
  79.     }
  80.    
  81.    BR->String=BL->String=block->String;
  82.    block->Left=BL;
  83.    block->Right=BR;
  84.    
  85.    /* Test auf Additive Blöcke */
  86.    if((Pos1=checkback('+','-',l,r,block->String))!=-1L)
  87.     {
  88.      LONG ll; /* Zum Speichern der linken Ecke */
  89.      ll=l;
  90.      /* Wenn ein entsprechendes Rechenzeichen gefunden wurde : */
  91.      do
  92.       {
  93.        /* Testet auf a^+-b                                      */
  94.        /* Pos1==ll testet, ob ein ^ überhaupt im Bereich ist,   */
  95.        /* denn das kann nur passieren, wenn ^ eins vor l (orig) */
  96.        /* ist. ll wird zwar immer erhöht, das Zeichen davor ist */
  97.        /* dann aber garantiert ein +-.                          */
  98.        
  99.        if((block->String[Pos1-1]!='^'&&block->String[Pos1-1]!='e'&&block->String[Pos1-1]!='d') || Pos1==ll)
  100.         {
  101.          Exponent_gefunden=FALSE;
  102.          
  103.          /* Solange aufmultiplizieren, bis alle Blöcke abgearbeitet sind */
  104.          Fehler|=ev(ll,Pos1-1L,BL); /* Subtrahiert Block bis Minuszeichen */
  105.          Fehler|=ev(Pos1+1L,r,BR);
  106.          if (block->String[Pos1]=='-')
  107.           {
  108.            block->RechenArt|=SUBT;
  109.           }
  110.          else
  111.           {
  112.            block->RechenArt|=ADDI;
  113.           }
  114.         }
  115.        else
  116.         {
  117.          Exponent_gefunden=TRUE;
  118.         }
  119.        Pos1=checkback('+','-',l,Pos1-1L,block->String);
  120.       }
  121.      while(Exponent_gefunden&&Pos1!=-1L);
  122.      if(!Exponent_gefunden)return(Fehler);
  123.     }
  124.    
  125.    
  126.    /* Test auf Multiplikative Blöcke */
  127.    if((Pos1=checkback('*','/',l,r,block->String))!=-1L)
  128.     {
  129.      /* Wenn Punktrechnung gefunden wurde : */
  130.       {
  131.        Fehler|=ev(l,Pos1-1L,BL);
  132.        Fehler|=ev(Pos1+1L,r,BR);
  133.        /* Solange Berechnen, bis kein Block mehr da */
  134.        if (block->String[Pos1]=='/')
  135.         {
  136.          block->RechenArt|=DIVI;
  137.         }
  138.        else
  139.         {
  140.          block->RechenArt|=MULT;
  141.         }
  142.       }
  143.      return(Fehler);
  144.     }
  145.    
  146.    
  147.      /* Abfrage auf Potenz                 */
  148.      /* Muß vor Abfrage auf Klammern sein  */
  149.      /* Getauscht : 07.09.1988             */
  150.    
  151.    if((Pos1=checkback('^','^',l,r,block->String))!=-1)
  152.     {
  153.      Fehler|=ev(l,Pos1-1L,BL);
  154.      Fehler|=ev(Pos1+1L,r,BR);
  155.      block->RechenArt|=POWE;
  156.      return(Fehler);
  157.     }
  158.    
  159.      /* Klammern um den Block ?                      */
  160.      /* nicht korrekte Abfrage, aber sicherer        */
  161.      /* Korrekt: Auf schließende Klammer testen      */
  162.      /* Bearbeitet gleichen Block weiter             */
  163.    
  164.    if (block->String[l]=='(')  
  165.     {
  166.      block->Left=block->Right=0;
  167.      FreeMem((UBYTE *)BL,sizeof(struct Block));
  168.      FreeMem((UBYTE *)BR,sizeof(struct Block));
  169.      if(!(block->String[r]==')'))
  170.       {
  171.        Fehler|=UNPAKLAM;
  172.        Fehler|=(ev(l+1L,r,block));
  173.       }
  174.      else
  175.       {
  176.        Fehler|=(ev(l+1L,r-1,block));
  177.       }
  178.      return(Fehler);
  179.     }
  180.    
  181.    FreeMem((UBYTE *)BL,sizeof(struct Block));
  182.    block->Left=NULL;
  183.    /* Abfrage der trigonometrischen Funktionen   */
  184.    /* Hier wird auf schließende Klammer getestet */
  185.    
  186.    Anzahl_Zeichen=0;
  187.    Pos1=min(5,r-l);
  188.    Hilfe[0]='_';
  189.    while(Anzahl_Zeichen<=Pos1&&block->String[l+Anzahl_Zeichen]!='(')
  190.     {
  191.      Hilfe[Anzahl_Zeichen]=block->String[l+Anzahl_Zeichen];
  192.      Anzahl_Zeichen++;
  193.     }
  194.    Hilfe[Anzahl_Zeichen]=0;
  195.    Pos1=search(Hilfe);
  196.    
  197.    if(Pos1<31&&Pos1>1)
  198.     {
  199.      Fehler|=(ev(l+(LONG)Anzahl_Zeichen,r,BR));
  200.     }
  201.    
  202.    
  203.    switch(Pos1)
  204.     {
  205.      /* int */
  206.      case 2:
  207.       {
  208.        block->RechenArt|=FLOO;
  209.        /*Fehler|=(ev(l+3L,r,BR));*/
  210.        break;
  211.       }
  212.      
  213.      /* Sinus */
  214.      case 6:
  215.       {
  216.        block->RechenArt|=SINU;
  217.        /*Fehler|=(ev(l+3L,r,BR));*/
  218.        break;
  219.       }
  220.      
  221.      /* Cosinus */
  222.      case 14:
  223.       {
  224.        block->RechenArt|=COSI;
  225.        /*Fehler|=(ev(l+3L,r,BR));*/
  226.        break;
  227.       }
  228.      
  229.      /* Tangens */
  230.      case 10:
  231.       {
  232.        block->RechenArt|=TANG;
  233.        /*Fehler|=(ev(l+3L,r,BR));*/
  234.        break;
  235.       }
  236.      
  237.      /* Wurzel Sqr */
  238.      case 17:
  239.       {
  240.        block->RechenArt|=SQRT;
  241.        /*Fehler|=ev(l+3L,r,BR);*/
  242.        break;
  243.       }
  244.      
  245.      /* log */
  246.      case 20:
  247.       {
  248.        block->RechenArt|=LOG1;
  249.        /*Fehler|=ev(l+3L,r,BR);*/
  250.        break;
  251.       }
  252.      
  253.      /* abs */
  254.      case 23:
  255.       {
  256.        block->RechenArt|=ABSO;
  257.        /*Fehler|=(ev(l+3L,r,BR));*/
  258.        break;
  259.       }
  260.      
  261.      /* sgn */
  262.      case 26:
  263.       {
  264.        block->RechenArt|=SIGU;
  265.        /*Fehler|=(ev(l+3L,r,BR));*/
  266.        break;
  267.       }
  268.      
  269.      /* ArcSinus */
  270.      case 5:
  271.       {
  272.        block->RechenArt|=ASIN;
  273.        /*Fehler|=ev(l+4L,r,BR);*/
  274.        break;
  275.       }
  276.      
  277.      /* ACosinus */
  278.      case 13:
  279.       {
  280.        block->RechenArt|=ACOS;
  281.        /*Fehler|=ev(l+4L,r,BR);*/
  282.        break;
  283.       }
  284.      
  285.      /* ArcTangens */
  286.      case 9:
  287.       {
  288.        block->RechenArt|=ATAN;
  289.        /*Fehler|=(ev(l+4L,r,BR));*/
  290.        break;
  291.       }
  292.      
  293.      /* ln */
  294.      case 29:
  295.       {
  296.        block->RechenArt|=LNAT;
  297.        /*Fehler|=ev(l+2L,r,BR);*/
  298.        break;
  299.       }
  300.      
  301.      /* x */
  302.      case 0:
  303.       {
  304.        block->RechenArt=X;
  305.        break;
  306.       }
  307.      
  308.      /* PI         */
  309.      case 31:
  310.       {
  311.        /* 07.09.1988 */
  312.        block->Wert=PI;
  313.        block->Valid=1;
  314.        block->RechenArt=MKON;
  315.        break;
  316.       }
  317.      
  318.      /* E          */
  319.      case 1:
  320.       {
  321.        /* 07.09.1988 */
  322.        block->Wert=E;
  323.        block->Valid=1;
  324.        block->RechenArt=MKON;
  325.        break;
  326.       }
  327.      
  328.      default:
  329.       {
  330.        /* Wenn der Block aus nur einen Zeichen besteht */
  331.        if(r==l&&(block->String[l]>='a'&&block->String[l]<='z'))
  332.         {
  333.          /* Abfrage der Konstanten a-d */
  334.          /* a-z        */
  335.          /* 05.10.1988 */
  336.          Pos1=block->Konstante=(block->String[l]-96);
  337.          if(Pos1<=0||Pos1>=26)Fehler|=NO_KONST;
  338.          
  339.          block->RechenArt=UKON;
  340.          FreeMem((UBYTE *)BR,sizeof(struct Block));
  341.          block->Right=NULL;
  342.         }
  343.        
  344.        /* Nur noch Ziffern */
  345.        if((block->String[l]>='0' && block->String[l]<='9')||block->String[l]=='.')
  346.         {
  347.          for (Pos1=l;Pos1<=r;Pos1++)
  348.           {
  349.            Ziffern[Pos1-l]=block->String[Pos1];
  350.           }
  351.          Ziffern[Pos1-l]=0;
  352.          UmwStoF(&block->Wert,Ziffern);
  353.          FreeMem((UBYTE *)BR,sizeof(struct Block));
  354.          block->Right=NULL;
  355.          block->RechenArt=ZIFF;
  356.         }
  357.        if(block->RechenArt==NULL)Fehler|=NO_FUNC;
  358.       }
  359.       /* ENDE default */
  360.     }
  361.     /* ENDE switch */
  362.    return(Fehler);
  363.   }
  364.  
  365.  
  366.  VOID __asm Free_Block(register __a0 struct Block *First)
  367.   {
  368.    struct Block *Links,*Rechts;
  369.    
  370.    Links=First->Left;
  371.    Rechts=First->Right;
  372.    
  373.    if(Links)Free_Block(Links);
  374.    if(Rechts)Free_Block(Rechts);
  375.    
  376.    FreeMem((UBYTE *)First,sizeof(struct Block));
  377.   }
  378.  
  379.  /* Gibt den Speicher wieder frei */
  380.  VOID __asm Free_Konst(register __a0 APTR Zeiger)
  381.   {
  382.    FreeMem((char *)Zeiger,26*sizeof(DOUBLE));
  383.   }
  384.  
  385.  /* Holt Speicher für Konstanten -> Null, wenn kein Erfolg */
  386.  APTR Init_Konst()
  387.   {
  388.    APTR Zeiger;
  389.    Zeiger=(APTR)AllocMem(26*sizeof(DOUBLE),MEMF_CLEAR);
  390.    return(Zeiger);
  391.   }
  392.  
  393.  /* Hilferoutine, die mit Zeigern auf DOUBLE arbeitet */
  394.  LONG __asm Set_Konst_P(register __a0 APTR Zeiger,register __d0 LONG Nummer,register __d1 DOUBLE *Wert_P)
  395.   {
  396.    DOUBLE Wert;
  397.    Wert=*Wert_P;
  398.    return(Set_Konst(Zeiger,Nummer,Wert));
  399.   }
  400.  
  401.  /* Setzt Konst-Nr. auf Wert */
  402.  LONG Set_Konst(APTR Zeiger,LONG Nummer,DOUBLE Wert)
  403.   {
  404.    DOUBLE *Z;
  405.    if(Nummer<=0||Nummer>=26)return(NO_KONST);
  406.    Z=(DOUBLE *)Zeiger;
  407.    Z[Nummer-1]=Wert;
  408.    return(0);
  409.   }
  410.  
  411.  struct Block * __asm Init_Mem(register __a0 char *string)
  412.   {
  413.    struct Block *FirstBlock;
  414.    FirstBlock=(struct Block *)AllocMem((sizeof(struct Block)),MEMF_CLEAR);
  415.    if(FirstBlock==NULL)return(0);
  416.    FirstBlock->Rechts=strlen(string)-1;
  417.    FirstBlock->String=string;
  418.    return(FirstBlock);
  419.   }
  420.  
  421.  LONG __asm Init_Block(register __a0 struct Block *Zeiger)
  422.   {
  423.    LONG Fehler;
  424.    Fehler=ev(0L,strlen(Zeiger->String)-1L,Zeiger);
  425.    return(Fehler);
  426.   }
  427.  
  428.  /* Hilfsroutine, die das nächste Auftreten eines der beiden Zeichen sucht */
  429.  LONG __asm check(register __d0 LONG z1,register __d1 LONG z2,
  430.                   register __d2 LONG l,register __d3 LONG r,
  431.                   register __a0 char *string)
  432.   {
  433.    int i,Klammern=0;
  434.    
  435.    for (i=l;i<=r;i++)
  436.     {
  437.      if (Klammern==0 && (string[i]==z1||string[i]==z2))
  438.       {
  439.        return(i); /* z1 gefunden */
  440.       }
  441.      if(string[i]=='(')
  442.       {
  443.        Klammern++; /* Auf anderer Klammerebene */
  444.       }
  445.      if(string[i]==')')
  446.       {
  447.        Klammern--;
  448.       }
  449.     }
  450.    return(-1); /* Nicht gefunden */
  451.   }
  452.  
  453.  /* Hilfsroutine, die das nächste Auftreten eines der beiden Zeichen sucht */
  454.  /* Sucht von hinten..                                                     */
  455.  LONG __asm checkback(register __d0 LONG z1,register __d1 LONG z2,
  456.                       register __d2 LONG l,register __d3 LONG r,
  457.                       register __a0 char *string)
  458.   {
  459.    int i,Klammern=0;
  460.    
  461.    for (i=r;i>=l;i--)
  462.     {
  463.      if (Klammern==0 && (string[i]==z1 || string[i]==z2))
  464.       {
  465.        return(i); /* z1 gefunden */
  466.       }
  467.      if(string[i]=='(')
  468.       {
  469.        Klammern++; /* Auf anderer Klammerebene */
  470.       }
  471.      if(string[i]==')')
  472.       {
  473.        Klammern--;
  474.       }
  475.     }
  476.    return(-1); /* Nicht gefunden */
  477.   }
  478.  
  479.  /* Hilfsroutine, die Teile des Strings kopiert */
  480.  VOID __asm copy(register __d0 LONG i,register __d1 LONG Anzahl,
  481.                  register __d2 char *Ziel,register __d3 char *Source)
  482.   {
  483.    int Schleife;
  484.    for (Schleife=i;Schleife<i+Anzahl;Schleife++)
  485.     {
  486.      *(Ziel+Schleife-i)=*(Source+Schleife);
  487.     }
  488.    *(Ziel+Schleife-i)=0;
  489.   }
  490.  
  491.  
  492.  /* Liefert Vorzeichen zurück */
  493.  double sgn(DOUBLE x)
  494.   {
  495.    DOUBLE Ergebnis;
  496.    if(Cmp(x,0.0)==1)
  497.     {
  498.      Ergebnis=1.0;
  499.     }
  500.    else
  501.     {
  502.      if(Cmp(x,0.0)==-1)
  503.       {
  504.        Ergebnis=-1.0;
  505.       }
  506.      else
  507.       {
  508.        Ergebnis=0.0;
  509.       }
  510.     }
  511.    return(Ergebnis);
  512.   }
  513.  
  514.  
  515.  LONG BereichsKontr(DOUBLE b)
  516.   {
  517.    if(Cmp(b,1.0)==1||Cmp(b,-1.0)==-1)
  518.     {
  519.      return(1);
  520.     }
  521.    return(0);
  522.   }
  523.  
  524.  
  525.  LONG __asm PreCalc(register __d0 struct Block *Zeiger,register __d1 APTR Konst)
  526.   {
  527.    DOUBLE Wert,links,rechts;
  528.    LONG Valid=1,v1,v2,Fehler=0;
  529.    Wert=Zeiger->Wert;
  530.    Zeiger->Fehler=Fehler;
  531.    if(Zeiger->Left )
  532.     {
  533.      Fehler=PreCalc(Zeiger->Left,Konst);
  534.      links =Zeiger->Left->Wert;
  535.      v1    =Zeiger->Left->Valid;
  536.     }
  537.    else
  538.     {
  539.      v1=1;
  540.     }
  541.    
  542.    if(Zeiger->Right)
  543.     {
  544.      Fehler|=PreCalc(Zeiger->Right,Konst);
  545.      rechts=Zeiger->Right->Wert;
  546.      v2    =Zeiger->Right->Valid;
  547.     }
  548.    else
  549.     {
  550.      v2=1;
  551.      /* Wenn rechts kein Block folgt, dann ist es der letzte Block */
  552.      Wert=Zeiger->Wert;
  553.     }
  554.    if(v1&&v2)
  555.     {
  556.      switch(Zeiger->RechenArt)
  557.       {
  558.        case ADDI:
  559.         {
  560.          Wert=Add(links,rechts);
  561.          break;
  562.         }
  563.        case SUBT:
  564.         {
  565.          Wert=Sub(links,rechts);
  566.          break;
  567.         }
  568.        case MULT:
  569.         {
  570.          Wert=Mul(links,rechts);
  571.          break;
  572.         }
  573.        case DIVI:
  574.         {
  575.          if(Tst(rechts))
  576.           {
  577.            Wert=Div(links,rechts);
  578.           }
  579.          else
  580.           {
  581.            Fehler|=DIVBYZERO;
  582.           }
  583.          break;
  584.         }
  585.        case POWE:
  586.         {
  587.          Wert=Pow(links,rechts);
  588.          /* Testet, ob Fehler aufgetreten ist. 0 -> 0^x oder neg^bruch ! */
  589.          if(Tst(Wert)==0&&Tst(links)!=0)Fehler|=POWERROR;
  590.          break;
  591.         }
  592.        case SINU:
  593.         {
  594.          Wert=Sin(rechts);
  595.          break;
  596.         }
  597.        case COSI:
  598.         {
  599.          Wert=Cos(rechts);
  600.          break;
  601.         }
  602.        case TANG:
  603.         {
  604.          Wert=Tan(rechts);
  605.          break;
  606.         }
  607.        case ASIN:
  608.         {
  609.          if(BereichsKontr(rechts))
  610.           {
  611.            Fehler|=ATRIG;
  612.           }
  613.          else
  614.           {
  615.            Wert=ASin(rechts);
  616.           }
  617.          break;
  618.         }
  619.        case ACOS:
  620.         {
  621.          if(BereichsKontr(rechts))
  622.           {
  623.            Fehler|=ATRIG;
  624.           }
  625.          else
  626.           {
  627.            Wert=ACos(rechts);
  628.           }
  629.          break;
  630.         }
  631.        case ATAN:
  632.         {
  633.          Wert=ATan(rechts);
  634.          break;
  635.         }
  636.        case LOG1:
  637.         {
  638.          if(Cmp(rechts,0.0)<=0L)
  639.           {
  640.            Fehler|=LOGNEG;
  641.           }
  642.          else
  643.           {
  644.            Wert=Log10(rechts);
  645.           }
  646.          break;
  647.         }
  648.        case LNAT:
  649.         {
  650.          if(Cmp(rechts,0.0)<=0L)
  651.           {
  652.            Fehler|=LOGNEG;
  653.           }
  654.          else
  655.           {
  656.            Wert=Log(rechts);
  657.           }
  658.          break;
  659.         }
  660.        case ABSO:
  661.         {
  662.          Wert=Abs(rechts);
  663.          break;
  664.         }
  665.        case SIGU:
  666.         {
  667.          Wert=sgn(rechts);
  668.          break;
  669.         }
  670.        case SQRT:
  671.         {
  672.          if(Tst(rechts)==-1L)
  673.           {
  674.            Fehler|=SQRTNEG;
  675.           }
  676.          else
  677.           {
  678.            Wert=Sqr(rechts);
  679.           }
  680.          break;
  681.         }
  682.        case FLOO:
  683.         {
  684.          Wert=Floor(rechts);
  685.          break;
  686.         }
  687.        case UKON:
  688.         {
  689.          if(Konst)Wert=GetKonst(Konst,(LONG)Zeiger->Konstante);
  690.          break;
  691.         }
  692.        case X:
  693.         {
  694.          Wert=0.0;
  695.          Valid=0;
  696.         }
  697.       }
  698.      Zeiger->Fehler|=Fehler;
  699.      if(Valid&&!Fehler)
  700.       {
  701.        Zeiger->Wert=Wert;
  702.        Zeiger->Valid=1;
  703.       }
  704.      else
  705.       {
  706.        Zeiger->Valid=0;
  707.       }
  708.     }
  709.    else
  710.     {
  711.      Zeiger->Valid=0;
  712.      Zeiger->Wert=NULL;
  713.     }
  714.    return(Fehler);
  715.   }
  716.  
  717.  /* Hilferoutine, die mit Zeigern auf DOUBLE arbeitet */
  718.  VOID __asm GetKonst_P(register __a0 DOUBLE *Ziel,
  719.                        register __a1 APTR Konst,
  720.                        register __d0 LONG Nummer)
  721.   {
  722.    DOUBLE Wert;
  723.    
  724.    Wert=GetKonst(Konst,Nummer);
  725.    Wert=Add(Wert,0.0);
  726.    *Ziel=Wert;
  727.   }
  728.  
  729.  DOUBLE __asm GetKonst(register __a0 APTR Konst,register __d1 LONG Nummer)
  730.   {
  731.    DOUBLE *Z;
  732.    if(Nummer<=0||Nummer>=26)return(0.0);
  733.    Z=(DOUBLE *)Konst;
  734.    return(Z[Nummer-1]);
  735.   }
  736.  
  737.  
  738.  /* Hilferoutine, die mit Zeigern auf DOUBLE arbeitet */
  739.  LONG __asm Calc_P(register __a0 DOUBLE *Ziel,
  740.                    register __a1 struct Block *Zeiger,
  741.                    register __a2 DOUBLE *x)
  742.   {
  743.    DOUBLE Wert;
  744.    DOUBLE Ergebnis;
  745.    struct Block *START;
  746.    
  747.    START=Zeiger;
  748.    Wert=*x;
  749.    Ergebnis=Calc(START,Wert);
  750.    *Ziel=Ergebnis;
  751.    return(Zeiger->Fehler);
  752.   }
  753.  
  754.  DOUBLE Calc(struct Block *Zeiger,DOUBLE x)
  755.   {
  756.    DOUBLE Wert=0.0,links,rechts;
  757.    LONG Fehler=0;
  758.    /* Evt. die obige Zeile raus und dafür unten Zeiger->Fehler=0 */
  759.    
  760.    Zeiger->Fehler=0; /* Löscht Fehler alter Durchläufe */
  761.    
  762.    if(Zeiger->Valid==1)return(Zeiger->Wert); /* Schon berechnet */ 
  763.    if(Zeiger->Left )
  764.     {
  765.      links=Calc(Zeiger->Left,x);
  766.      Fehler|=Zeiger->Left->Fehler;
  767.     }
  768.    if(Zeiger->Right)
  769.     {
  770.      rechts=Calc(Zeiger->Right,x);
  771.      Fehler|=Zeiger->Right->Fehler;
  772.     }
  773.    else
  774.     {
  775.      Wert=Zeiger->Wert;
  776.     }
  777.    switch(Zeiger->RechenArt)
  778.     {
  779.      case ADDI:
  780.       {
  781.        Wert=Add(links,rechts);
  782.        break;
  783.       }
  784.      case SUBT:
  785.       {
  786.        Wert=Sub(links,rechts);
  787.        break;
  788.       }
  789.      case MULT:
  790.       {
  791.        Wert=Mul(links,rechts);
  792.        break;
  793.       }
  794.      case DIVI:
  795.       {
  796.        if(Tst(rechts))
  797.         {
  798.          Wert=Div(links,rechts);
  799.         }
  800.        else
  801.         {
  802.          Fehler|=DIVBYZERO;
  803.         }
  804.        break;
  805.       }
  806.      case POWE:
  807.       {
  808.        Wert=Pow(links,rechts);
  809.        if(Tst(Wert)==0&&Tst(links)!=0)Fehler|=POWERROR;
  810.        break;
  811.       }
  812.      case SINU:
  813.       {
  814.        Wert=Sin(rechts);
  815.        break;
  816.       }
  817.      case COSI:
  818.       {
  819.        Wert=Cos(rechts);
  820.        break;
  821.       }
  822.      case TANG:
  823.       {
  824.        Wert=Tan(rechts);
  825.        break;
  826.       }
  827.      case ASIN:
  828.       {
  829.        if(BereichsKontr(rechts))
  830.         {
  831.          Fehler|=ATRIG;
  832.         }
  833.        else
  834.         {
  835.          Wert=ASin(rechts);
  836.         }
  837.        break;
  838.       }
  839.      case ACOS:
  840.       {
  841.        if(BereichsKontr(rechts))
  842.         {
  843.          Fehler|=ATRIG;
  844.         }
  845.        else
  846.         {
  847.          Wert=ACos(rechts);
  848.         }
  849.        break;
  850.       }
  851.      case ATAN:
  852.       {
  853.        Wert=ATan(rechts);
  854.        break;
  855.       }
  856.      case LOG1:
  857.       {
  858.        if(Cmp(rechts,0.0)<=0)
  859.         {
  860.          Fehler|=LOGNEG;
  861.         }
  862.        else
  863.         {
  864.          Wert=Log10(rechts);
  865.         }
  866.        break;
  867.       }
  868.      case LNAT:
  869.       {
  870.        if(Cmp(rechts,0.0)<=0)
  871.         {
  872.          Fehler|=LOGNEG;
  873.         }
  874.        else
  875.         {
  876.          Wert=Log(rechts);
  877.         }
  878.        break;
  879.       }
  880.      case ABSO:
  881.       {
  882.        Wert=Abs(rechts);
  883.        break;
  884.       }
  885.      case SIGU:
  886.       {
  887.        Wert=sgn(rechts);
  888.        break;
  889.       }
  890.      case SQRT:
  891.       {
  892.        if(Tst(rechts)==-1L)
  893.         {
  894.          Fehler|=SQRTNEG;
  895.         }
  896.        else
  897.         {
  898.          Wert=Sqr(rechts);
  899.         }
  900.        break;
  901.       }
  902.      case FLOO:
  903.       {
  904.        Wert=Floor(rechts);
  905.        break;
  906.       }
  907.      case UKON:
  908.       {
  909.        Wert=Zeiger->Wert;
  910.        break;
  911.       }
  912.      case X:
  913.       {
  914.        Wert=x;
  915.       }
  916.     }
  917.    Zeiger->Fehler|=Fehler;
  918.    return(Wert);
  919.   }
  920.  
  921.  
  922.  LONG __asm AnzahlKlammern(register __a0 char *string)
  923.   {
  924.    int Laenge,Klammern;
  925.    unsigned short i;
  926.    Klammern=0;
  927.    Laenge=strlen(string)-1;
  928.    for(i=0;i<=Laenge;i++)
  929.     {
  930.      if(string[i]=='(')Klammern++;
  931.      if(string[i]==')')Klammern--;
  932.     }
  933.    return(Klammern);
  934.   }
  935.  
  936.  VOID __asm berechnen(register __a0 DOUBLE *Ziel,
  937.                       register __d0 UBYTE *string,
  938.                       register __d1 DOUBLE *var,
  939.                       register __d2 struct Konstanten *kon,
  940.                       register __d3 LONG *Fehler)
  941.   {
  942.    LONG f;
  943.    DOUBLE Wert;
  944.    DOUBLE Ruckgabe;
  945.    struct Block *START;
  946.    
  947.    Wert=*var;
  948.    
  949.    START=Init_Mem(string);
  950.    f=Init_Block(START);
  951.    *Fehler=f;
  952.    
  953.    f=PreCalc(START,(APTR)kon);   /* Nötig, um Konstanten einzubinden */
  954.    Ruckgabe=Calc(START,Wert);
  955.    *Fehler|=f;
  956.    
  957.    Free_Block(START);
  958.    
  959.    *Ziel=Ruckgabe;
  960.   }
  961.  
  962.